package com.mcy.gles.mesh.cube;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.opengl.GLU;
import android.opengl.GLSurfaceView.Renderer;

public class CubeRenderer implements Renderer {

	//顶点数组
	float box[] = new float[] {
			// FRONT
			-0.5f, -0.5f,  0.5f,
			 0.5f, -0.5f,  0.5f,
			-0.5f,  0.5f,  0.5f,
			 0.5f,  0.5f,  0.5f,
			// BACK
			-0.5f, -0.5f, -0.5f,
			-0.5f,  0.5f, -0.5f,
			 0.5f, -0.5f, -0.5f,
			 0.5f,  0.5f, -0.5f,
			// LEFT
			-0.5f, -0.5f,  0.5f,
			-0.5f,  0.5f,  0.5f,
			-0.5f, -0.5f, -0.5f,
			-0.5f,  0.5f, -0.5f,
			// RIGHT
			 0.5f, -0.5f, -0.5f,
			 0.5f,  0.5f, -0.5f,
			 0.5f, -0.5f,  0.5f,
			 0.5f,  0.5f,  0.5f,
			// TOP
			-0.5f,  0.5f,  0.5f,
			 0.5f,  0.5f,  0.5f,
			 -0.5f,  0.5f, -0.5f,
			 0.5f,  0.5f, -0.5f,
			// BOTTOM
			-0.5f, -0.5f,  0.5f,
			-0.5f, -0.5f, -0.5f,
			 0.5f, -0.5f,  0.5f,
			 0.5f, -0.5f, -0.5f,
		};

	FloatBuffer cubeBuff;
	GL10 mGL;
	
	// 旋转角度
	float xrot = 0.0f;
	float yrot = 0.0f;
	// 旋转角速度（递增量）
	float xspd = 1.0f;
	float yspd = 0.5f;
	
	/**
	 * 将浮点数组保存到缓冲转换存储到字节缓冲数组
	 * @param arr
	 * @return
	 */
	public FloatBuffer makeFloatBuffer(float[] arr) {
		//分配缓存空间，一个float占4个字节
		ByteBuffer bb = ByteBuffer.allocateDirect(arr.length * 4);
		//调整字节编码顺序，nativeOrder是获取本机字节顺序（机器字节编码有大小头之分）
		bb.order(ByteOrder.nativeOrder()); 
		//转为float类型
		FloatBuffer fb = bb.asFloatBuffer(); 
		//添加数据
		fb.put(arr);
		//设置数组的起始位置
		fb.position(0);
		return fb;
	}
	
	public CubeRenderer() {
		cubeBuff = makeFloatBuffer(box);//转换float数组
	}
	
	protected void init(GL10 gl) {
		// 设置清屏时颜色RGBA模式
		gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
		// 启用深度缓存
		gl.glEnable(GL10.GL_DEPTH_TEST);
		// 启用面剪裁
		gl.glEnable(GL10.GL_CULL_FACE);
		// 设置深度缓存值
		gl.glClearDepthf(1.0f);
		/* 设置深度缓存比较函数，
		 * GL_LEQUAL表示新的像素的深度缓存值小于等于当前像素的深度缓存值
		 *（通过gl.glClearDepthf(1.0f)设置）时通过深度测试
		 */	
		gl.glDepthFunc(GL10.GL_LEQUAL);
		// 设置阴影模式
		gl.glShadeModel(GL10.GL_SMOOTH);
	}
	
	@Override
	public void onSurfaceCreated(GL10 gl, EGLConfig config) {
		init(gl);
		mGL = gl;
	}
	
	@Override
	public void onSurfaceChanged(GL10 gl, int w, int h) {
		gl.glViewport(0, 0, w, h); // 设置视窗
		gl.glMatrixMode(GL10.GL_PROJECTION); // 设置投影矩阵
		gl.glLoadIdentity();  // 设置矩阵为单位矩阵，相当于重置矩阵		
		GLU.gluPerspective(gl, 45.0f, ((float) w) / h, 0.1f, 10f);// 设置透视范围
	}
	
	/**
	 * 绘当前帧图像时调用
	 */
	@Override
	public void onDrawFrame(GL10 gl) {
		// 清楚屏幕和深度缓存
		gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); 
		// 切换至模型观察矩阵
		gl.glMatrixMode(GL10.GL_MODELVIEW);
		// 重置当前的模型观察矩阵
		gl.glLoadIdentity(); 
		// 设置视点和模型中心位置
		GLU.gluLookAt(gl, 0, 0, 3, 0, 0, 0, 0, 1, 0); 
	    
		// 设置顶点数据
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, cubeBuff); 
		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
	
		// 围绕(0,0,0)与(1,0,0)即X轴旋转
		gl.glRotatef(xrot, 1, 0, 0);  
		// 围绕(0,0,0)与(0,1,0)即Y轴旋转
		gl.glRotatef(yrot, 0, 1, 0);
		
		// 设置颜色(RGBA)，红色
		gl.glColor4f(1.0f, 0, 0, 1.0f); 
		// 绘制正方形的FRONT面
		gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
		// 绘制正方形的BACK面
		gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 4, 4);
	
		// 绿色
		gl.glColor4f(0, 1.0f, 0, 1.0f);
		gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 8, 4);
		gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 12, 4);
		
		// 蓝色
		gl.glColor4f(0, 0, 1.0f, 1.0f);
		gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 16, 4);
		gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 20, 4);
	
		xrot += xspd;
		yrot += yspd;
	}
	
    /**
     * 开始旋转
     */
	public void startRotation() {
		// 角速度恢复
		xspd = 1.0f;
		yspd = 0.5f;
	}
	
	/**
	 * 停止旋转
	 */
	public void stopRotation(){

		// 角速度设为0
		xspd = 0.0f;
		yspd = 0.0f;
	}
	
}
